<?php

class Rapide_Database_MySQL extends Rapide_Database
{
	const FETCH_ROW	 = 1;
	const FETCH_ASSOC = 2;
	const FETCH_ARRAY = 3;

	private
		$_rDatabaseHandle,
		$_rQuery,
		$_iFetchMode = self::FETCH_ASSOC;

	public function connect()
	{
		if($this->_aParameters['persistent'])
		{
			$rHandle = mysql_pconnect($this->_aParameters['host'], $this->_aParameters['user'], $this->_aParameters['password']);
		}
		else
		{
			$rHandle = mysql_connect($this->_aParameters['host'], $this->_aParameters['user'], $this->_aParameters['password']);
		}

		if($rHandle)
			$this->_rDatabaseHandle = $rHandle;
		else
		{
			$sError = 'Can not connect to database';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		$bResult = mysql_select_db($this->_aParameters['database'], $this->_rDatabaseHandle);

		if(!$bResult)
		{
			$sError = 'Can not select database';
			throw new Rapide_Database_MySQL_Exception($sError);
		}
	}

	public function disconnect()
	{
		if(!isset($this->_rDatabaseHandle))
		{
			$sError = 'Database is not connected';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		return mysql_close($this->_rDatabaseHandle);
	}

	public function setFetchMode($iFetchMode)
	{
		switch($iFetchMode)
		{
			case self::FETCH_ARRAY:
			case self::FETCH_ASSOC:
			case self::FETCH_ROW:
				$this->_iFetchMode = $iFetchMode;
				break;

			default:
				$sError = 'Wrong get mode has been set';
				throw new Rapide_Database_MySQL_Exception($sError);
		}
	}

	public function exec($sQuery)
	{
		if(isset($this->_rQuery))
			unset($this->_rQuery);

		$rResult = mysql_query($sQuery, $this->_rDatabaseHandle);

		array_push($this->_aQueryStack, $sQuery);

		if(!$rResult)
		{
			$sError = sprintf('Query %s failed', $sQuery);
			throw new Rapide_Database_MySQL_Exception($sError);
		}
		else
			$this->_rQuery = $rResult;
	}

	public function getNumOfAffectedRows()
	{
		if(!isset($this->_rQuery))
		{
			$sError = 'Database has not been queried';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		return mysql_affected_rows($this->_rDatabaseHandle);
	}

	public function getInsertId()
	{
		if(!isset($this->_rQuery))
		{
			$sError = 'Database has not been queried';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		$this->exec('SELECT LAST_INSERT_ID()');

		return $this->fetchOne();
	}

	public function getNumOfRows()
	{
		if(!isset($this->_rQuery))
		{
			$sError = 'Database has not been queried';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		return mysql_num_rows($this->_rQuery);
	}

	public function fetch()
	{
		if(!isset($this->_rQuery))
		{
			$sError = 'Database has not been queried';
			throw new Rapide_Database_MySQL_Exception($sError);
		}

		switch($this->_iFetchMode)
		{
			case self::FETCH_ARRAY:
				$aFetch = mysql_fetch_array($this->_rQuery);
				break;

			case self::FETCH_ASSOC:
				$aFetch = mysql_fetch_assoc($this->_rQuery);
				break;

			case self::FETCH_ROW:
				$aFetch = mysql_fetch_row($this->_rQuery);
				break;
		}

		if(is_array($aFetch))
		{
			foreach($aFetch as $sKey => $mValue)
				$aFetch[$sKey] = stripslashes($mValue);
		}

		return $aFetch;
	}

	public function fetchOne()
	{
		$iFetchMode = $this->_iFetchMode;

		$this->setFetchMode(self::FETCH_ROW);
		$aRow = $this->fetch();

		$this->setFetchMode($iFetchMode);

		if(is_array($aRow))
			return $aRow[0];
		else
			return false;
	}

	public function fetchAll()
	{
		$aFetch = array();

		while($aRow = $this->fetch())
			$aFetch[] = $aRow;

		return $aFetch;
	}

	public function fetchCol($iColumn = 0)
	{
		$iColumn = intval($iColumn);

		$iFetchMode = $this->_iFetchMode;
		$this->setFetchMode(self::FETCH_ARRAY);

		$aFetch = array();

		while($aRow = $this->fetch())
			$aFetch[] = $aRow[$iColumn];
		
		$this->setFetchMode($iFetchMode);

		return $aFetch;
	}

	public function query($sQuery)
	{
		$this->exec($sQuery);
	}
}

?>